<template>
	<a-spin :spinning="config.spinning">
		<div class="container" ref="container">
		</div>
	</a-spin>

</template>

<script setup>
import {defineProps, onMounted} from 'vue'
import processComponentApi from '@/api/process/processComponentApi.js'
import {nextTick} from "@/utils";
// import config from '@/config'

const container = ref()
const props = defineProps(['id', 'nodeId', 'frontFile', 'componentConfig', 'basicConfig', 'component'])

const config = ref({
	spinning: false,
	version: null,
	getDataFlag: false,
	data: null
})

onMounted(() => {
	// props.properties?.basicConfig?.version
	nextTick(() => {
		createIframe()
	})
	listenerMessage()
})
//组件销毁的时候去除监听事件
onUnmounted(() => {
	window.removeEventListener('message', messageProcess, false)
})

const getVersion = () => {
	if (!props.basicConfig) {
		return '';
	}
	return props.basicConfig.version || '';
}

let iframe = null;


const createIframe = async () => {
	//创建一把
	iframe = document.createElement('iframe');
	iframe.id = "fm-" + props.nodeId;
	iframe.name = iframe.id;
	iframe.frameBorder = "0";
	iframe.allow = "fullscreen";
	iframe.width = "100%";
	if (!container.value.offsetHeight) {
		iframe.height = container.value.parentElement.offsetHeight;
	} else {
		iframe.height = container.value.offsetHeight;
	}
	config.value.spinning = true;
	let vHtml = await processComponentApi.getHtml(props.component.type, getVersion());
	if (!vHtml) {
		vHtml = "<div>该组件没有找到视图</div>";
	}
	vHtml = buildHtml(vHtml)

	const blob = new Blob([vHtml], {
		type: "text/html"
	});
	let objectURL = window.URL.createObjectURL(blob);
	iframe.src = objectURL;
	//追加进去
	container.value.append(iframe);
	iframe.onload = () => {
		frameLoadEvent();
		//关闭loading
		config.value.spinning = false;
	}
}
const frameLoadEvent = () => {
	const data = {...props.componentConfig}
	data.versionId = props.id;
	data.resource = props.frontFile;
	// data.processVersion = getVersion();
	data.stepCode = props.nodeId;
	postMessage('setData', data);
}

const postMessage = (type, data) => {
	iframe.contentWindow.postMessage(JSON.stringify({type: type, data: data || null}), "*");
}


const listenerMessage = () => {
	//先删除，在添加
	window.addEventListener('message', messageProcess, false);
}

const messageProcess = (e) => {
	// 监听 message 事件
	const d = e.data;
	if (d && typeof (d) == 'string') {
		let json = {};
		try {
			json = JSON.parse(d);
		} catch (e) {
			console.log("不是一个json")
		}
		if (json.type == "getData") {
			config.value.data = json.data;
		}
	}
}
const getComponentConfig = () => {
	let iframe = document.getElementById('fm-' + props.nodeId);
	if (!iframe) {
		return
	}

	//发送获取数据的消息
	postMessage('getData');
	//开启来
	// config.value.whileGetDataFlag = true;
	return new Promise((resolve, reject) => {
		config.value.getDataFlag = true;
		whileGetData((data) => {
			resolve(data);
			config.value.getDataFlag = false;
		})
	})
}


const whileGetData = (callback) => {
	if (config.value.getDataFlag) {
		if (config.value.data != null) {
			callback(config.value.data);
		} else {
			nextTick(() => {
				whileGetData(callback);
			})
		}
	} else {
		callback(config.value.data);
	}
}

const buildHtml = (vHtml) => {
	const host = getHost()
	let newHtml = vHtml.substring(0, vHtml.lastIndexOf("</"));
	let endTag = vHtml.substring(vHtml.lastIndexOf("</"));
	//引入css
	newHtml += `<link type='text/javascript' id="css-fm-${props.nodeId}" rel="stylesheet" href="${host}/process/component/css?code=${props.component.type}&version=${getVersion()}"/>`;

	//自定义js
	newHtml = buildCustomJs(newHtml)

	//引入js
	newHtml += `<script type='text/javascript' id="script-fm-${props.nodeId}" src="${host}/process/component/js?code=${props.component.type}&version=${getVersion()}"><\/script>`

	newHtml = buildMessageEventListener(newHtml);
	newHtml += endTag;


	return newHtml;
}

const buildMessageEventListener = (newHtml) => {
	newHtml += `<script type='text/javascript' id="script-message-fm-${props.nodeId}">
		window.addEventListener("message", function(event) {
             var d= event.data;
             if(d){
                  var parse = null;
                 if(typeof d =='string'){
                         parse = JSON.parse(d);
                 }else{
                     parse = d;
                 }
                 if(parse&&parse.type=="setData"){
                     window.editor.setData(parse.data);
                 }else if(parse&&parse.type=="getData"){
                     let param = {
                         type:"getData",
                         data:window.editor.getData()
                     }
                     window.parent.postMessage(JSON.stringify(param),"*");
                 }
             }
	});
	<\/script>`
	return newHtml;
}
const buildCustomJs = (newHtml) => {
	newHtml += `<script type='text/javascript' id="script-framework-fm-${props.nodeId}">
        window.onload = function(){
			if(!window.accessGet){
				console.log("没有找到window.accessGet函数");
			}
			if(!window.accessSet){
				console.log("没有找到window.accessSet函数");
			}
        }
		window.editor={
          data:null,
          getData:function(){
              if(window.bindData){
                  this.data = window.bindData;
              }
              if(window.accessGet){
                 this.data =  window.accessGet();
             }
          return this.data;
          },
          setData:function(data){
              if(window.bindData!=null){
                 var keys = Object.keys(data);
                      keys.forEach(v => {
                          window.bindData[v] = data[v];
                      })
              }
                  if(window.accessSet){
                      window.accessSet(data);
                  }
              this.data = data;
          }
	}<\/script>`;
	return newHtml;
}
const getHost = () => {
	console.log(window.location.host)
	return window.location.host + "/api";
}

defineExpose({
	getComponentConfig
})
</script>

<style scoped lang="less">
.container {
	height: 500px;
	width: 100%;
}
</style>
